#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Build-in / Std

'''
Created on 2016年8月23日

@author: Hawk
'''

import os
import datetime
from peewee import *

class SqliteDatabaseWarpper(SqliteDatabase):
    def register(self, cls):
        cls._meta.database = self

class SuperBaseModel(Model):
    #class Meta:
    #    database = database

    @classmethod
    def getOne(cls, *query, **kwargs):
        try:
            return cls.get(*query, **kwargs)
        except DoesNotExist:
            return None

    @classmethod
    def map(cls, database):
        cls._meta.database = database

    @classmethod
    def get_fields(cls):
        return [ k for k in cls._meta.fields ]

    @classmethod
    def create_with_args(cls, *args, **kwargs):
        obj = cls()
        for attr in cls._meta.fields:
            if attr in kwargs:
                setattr(obj, attr, kwargs[attr])
        return obj

class Operation(SuperBaseModel):
    # 操作ID
    id = IntegerField(primary_key=True)

    # 创建时间
    create_time = DateTimeField(default=datetime.datetime.now)

    # 操作名称
    name = CharField()

    # 目标表格
    table = CharField()

    # 原始数据
    original = CharField(null=True, constraints=[SQL("DEFAULT NULL")])

    # 新数据
    current = CharField(null=False)

    class Meta:
        db_table = "pm_operations"
        order_by = ('id',)

class BaseModel(SuperBaseModel):
    def save(self, force_insert=False, only=None):
        model_class = self._meta.model_class
        origional_data = model_class.getOne(model_class.id == self.id)
        original_data_map = None
        operation_name = u'Add'
        if origional_data:
            operation_name = u'Modify'
            original_data_map = origional_data._data

        Operation.create_with_args(name=operation_name,
                                   original=original_data_map,
                                   current=self._data,
                                   table=self._meta.db_table).save()

        return Model.save(self, force_insert=force_insert, only=only)

class Category(BaseModel):
    '''项目类别'''

    # 类别ID
    id = IntegerField(primary_key=True)

    # 类别名称
    name = CharField(unique=True)

    # 创建时间
    create_time = DateTimeField(default=datetime.datetime.now)

    # 更新时间
    update_time = DateTimeField(constraints=[SQL('DEFAULT CURRENT_TIMESTAMP')])

    # 是否已删除
    deleted = BooleanField(default=False)
    comment = CharField(null=True, constraints=[SQL("DEFAULT NULL")])

    class Meta:
        db_table = "pm_categories"
        order_by = ('id',)

class Project(BaseModel):
    '''项目'''

    # 产品ID
    id = IntegerField(primary_key=True)

    # 产品名称
    name = CharField(unique=True, null=False)

    # 产品类别
    category = ForeignKeyField(Category, related_name='projects')

    # 软体负责人
    owner = CharField(null=False)

    #电子负责人
    ee_owner = CharField(null=False)

    # 更新时间
    update_time = DateTimeField(default=datetime.datetime.now)

    # skus, foreignKey From Sku

    # 是否已删除
    deleted = BooleanField(default=False)

    comment = CharField(null=True, constraints=[SQL("DEFAULT NULL")])

    class Meta:
        db_table = "pm_projects"
        order_by = ('id',)

class Sku(BaseModel):
    '''记录管理所有SKU'''

    # SKU ID
    id = IntegerField(primary_key=True)

    # SKU名称
    name = CharField(unique=True)

    # 创建时间
    create_time = DateTimeField(default=datetime.datetime.now)

    # 更新时间
    update_time = DateTimeField(constraints=[SQL('DEFAULT CURRENT_TIMESTAMP')])

    # 是否已删除
    deleted = BooleanField(default=False)

    comment = CharField(null=True, constraints=[SQL("DEFAULT NULL")])

    class Meta:
        db_table = "pm_skus"
        order_by = ('id',)

class Product(BaseModel):
    '''记录管理所有Project所有SKU的数据'''

    # SKU ID
    id = IntegerField(primary_key=True)

    # 所属project id
    project = ForeignKeyField(Project, related_name='products')

    # 所属sku id
    sku = ForeignKeyField(Sku, related_name='products')

    # 负责人
    owner = CharField()

    # 107FRM签核日期
    frm107_date = DateField(null=False)

    # MP日期
    mp_date = DateField(null=False)

    # 开发人力MM
    #development_mm = FloatField(default=0.0)

    # 维护阶段人力MM
    #maintenance_mm = FloatField(default=0.0)

    # 更新时间
    update_time = DateTimeField(default=datetime.datetime.now)

    # 是否已删除
    deleted = BooleanField(default=False)

    comment = CharField(null=True, constraints=[SQL("DEFAULT NULL")])

    class Meta:
        db_table = "pm_products"
        order_by = ('id',)

class Record(BaseModel):
    '''操作记录'''

    # 记录 ID
    id = IntegerField(primary_key=True)

    # 发行日期
    date = DateField(null=False)

    # 所属project id
    product = ForeignKeyField(Product, related_name='records')

    # 发行版本
    version = CharField()

    # 基于WW版本
    ww_version = CharField()

    # WW版发行时间
    ww_date = DateField(null=True, constraints=[SQL("DEFAULT NULL")])

    # 开发人力MM
    development_mm = FloatField()

    # 维护阶段人力MM
    maintenance_mm = FloatField()

    # 是否Sync WW
    is_sync_ww = BooleanField()

    # 是否为MP软体
    is_mp = BooleanField(default=False)

    # 更新时间
    update_time = DateTimeField(default=datetime.datetime.now)

    # 是否已删除
    deleted = BooleanField(default=False)

    comment = CharField(null=True, constraints=[SQL("DEFAULT NULL")])

    class Meta:
        db_table = "pm_records"
        order_by = ('id',)

if __name__ == '__main__':
    _db_name_ = "test.db"

    is_creating_table = not os.path.exists(_db_name_)
    database = SqliteDatabaseWarpper(_db_name_)

    #Category.map(database)
    #Project.map(database)
    #Sku.map(database)
    #Record.map(database)
    #Product.map(database)
    database.register(Category)
    database.register(Project)
    database.register(Sku)
    database.register(Record)
    database.register(Product)

    print Category.get_fields()

    if is_creating_table:
        print 'creating tables and insert test data...'
        def create_tables():
            database.connect()
            database.create_tables([Category, Project, Sku, Record, Product], safe=True)

        create_tables()

        categories = [
                      {'name': 'Recreational'},
                      {'name': 'Motorcycle'},
                      {'name': 'Golf'},
                      {'name': 'Watch'},
                      ]
        for c in categories:
            cat = Category()
            cat.name = c['name']
            cat.save()

        projects = [
                    {'name': 'oregon7xx', 'category': 1, 'owner': 'Best', 'ee_owner': 'Kevin'},
                    {'name': 'zumo660', 'category': 2, 'owner': 'Best', 'ee_owner': 'Kevin'},
                    {'name': 'fenix3', 'category': 4, 'owner': 'Best', 'ee_owner': 'Kevin'},
                    {'name': 'fenix3hr', 'category': 4, 'owner': 'Best', 'ee_owner': 'Kevin'},
                    {'name': 'gpsmap64s', 'category': 1, 'owner': 'Best', 'ee_owner': 'Kevin'},
                    {'name': 'gpsmap64sc', 'category': 1, 'owner': 'Best', 'ee_owner': 'Kevin'},
                    {'name': 'gpsmap62sc', 'category': 1, 'owner': 'Best', 'ee_owner': 'Kevin'},
                    {'name': 's2', 'category': 3, 'owner': 'Best', 'ee_owner': 'Kevin'},
                    {'name': 's4', 'category': 3, 'owner': 'Best', 'ee_owner': 'Kevin'},
                    {'name': 's6', 'category': 3, 'owner': 'Best', 'ee_owner': 'Kevin'},
                    {'name': 's20', 'category': 3, 'owner': 'Best', 'ee_owner': 'Kevin'},
                    ]
        for p in projects:
            pro = Project()
            pro.name = p['name']
            pro.category = p['category']
            pro.owner = p['owner']
            pro.ee_owner = p['ee_owner']
            pro.save()

        skus = [
                {'name': 'APAC'},
                {'name': 'CHN'},
                {'name': 'TWN'},
                {'name': 'JPN'},
                {'name': 'KOR'},
                {'name': 'SEA'},
                {'name': 'IND'},
                ]
        for s in skus:
            sk = Sku()
            sk.name = s['name']
            sk.save()

        project_skus = [
                {'name': 'APAC', 'project': 1, 'sku': 1, 'owner': 'Best', 'frm107_date': 201606, 'mp_date': 201607, 'development_mm': 0, 'maintenance_mm': 0},

                {'name': 'CHN', 'project': 2, 'sku': 2, 'owner': 'Best', 'frm107_date': 201606, 'mp_date': 201607, 'development_mm': 0, 'maintenance_mm': 0},
                {'name': 'TWN', 'project': 2, 'sku': 3, 'owner': 'Best', 'frm107_date': 201606, 'mp_date': 201607, 'development_mm': 0, 'maintenance_mm': 0},
                {'name': 'JPN', 'project': 2, 'sku': 4, 'owner': 'Best', 'frm107_date': 201606, 'mp_date': 201607, 'development_mm': 0, 'maintenance_mm': 0},

                {'name': 'CHN', 'project': 3, 'sku': 2, 'owner': 'Best', 'frm107_date': 201606, 'mp_date': 201607, 'development_mm': 0, 'maintenance_mm': 0},
                {'name': 'TWN', 'project': 3, 'sku': 3, 'owner': 'Best', 'frm107_date': 201606, 'mp_date': 201607, 'development_mm': 0, 'maintenance_mm': 0},
                {'name': 'JPN', 'project': 3, 'sku': 4, 'owner': 'Best', 'frm107_date': 201606, 'mp_date': 201607, 'development_mm': 0, 'maintenance_mm': 0},

                {'name': 'APAC', 'project': 4, 'sku': 1, 'owner': 'Best', 'frm107_date': 201606, 'mp_date': 201607, 'development_mm': 0, 'maintenance_mm': 0},

                {'name': 'CHN', 'project': 5, 'sku': 2, 'owner': 'Best', 'frm107_date': 201606, 'mp_date': 201607, 'development_mm': 0, 'maintenance_mm': 0},
                {'name': 'TWN', 'project': 5, 'sku': 3, 'owner': 'Best', 'frm107_date': 201606, 'mp_date': 201607, 'development_mm': 0, 'maintenance_mm': 0},
                {'name': 'JPN', 'project': 5, 'sku': 4, 'owner': 'Best', 'frm107_date': 201606, 'mp_date': 201607, 'development_mm': 0, 'maintenance_mm': 0},
                ]
        for s in project_skus:
            sk = Product()
            sk.project = s['project']
            sk.sku = s['sku']
            sk.owner = s['owner']
            sk.frm107_date = s['frm107_date']
            sk.mp_date = s['mp_date']
            sk.development_mm = s['development_mm']
            sk.maintenance_mm = s['maintenance_mm']
            sk.save()

        records = [
                   {'date': 201601, 'project': 1, 'sku': 1, 'version':'2.00', 'ww_version': '2.20', 'development_mm': 0.5, 'maintenance_mm': 3, 'is_sync_ww': 0},
                   {'date': 201602, 'project': 1, 'sku': 1, 'version':'2.00', 'ww_version': '2.20', 'development_mm': 0.5, 'maintenance_mm': 3, 'is_sync_ww': 0},
                   {'date': 201603, 'project': 1, 'sku': 1, 'version':'2.00', 'ww_version': '2.20', 'development_mm': 0.53, 'maintenance_mm': 3, 'is_sync_ww': 0},
                   {'date': 201604, 'project': 1, 'sku': 1, 'version':'2.00', 'ww_version': '2.20', 'development_mm': 0.53, 'maintenance_mm': 3, 'is_sync_ww': 0},
                   {'date': 201605, 'project': 1, 'sku': 1, 'version':'2.00', 'ww_version': '2.20', 'development_mm': 0.52, 'maintenance_mm': 3, 'is_sync_ww': 0},
                   {'date': 201606, 'project': 1, 'sku': 1, 'version':'2.00', 'ww_version': '2.20', 'development_mm': 0.51, 'maintenance_mm': 3, 'is_sync_ww': 0},
                   ]
        for r in records:
            rec = Record()
            rec.date = r['date'];
            rec.project = r['project'];
            rec.sku = r['sku'];
            rec.version = r['version'];
            rec.ww_version = r['ww_version'];
            rec.development_mm = r['development_mm'];
            rec.maintenance_mm = r['maintenance_mm'];
            rec.is_sync_ww = r['is_sync_ww'];
            rec.save()

        # update data
        for r in records:
            sk = Product.select().where(Product.id == r['sku']).get()
            sk.development_mm += r['development_mm']
            sk.maintenance_mm += r['maintenance_mm']
            sk.save()
    else:
        print '-' * 40
        for p in Project.select():
            for s in p.skus:
                print p.name, s.sku.name
            for r in p.records:
                print r.date

        print '-' * 40
        for r in Record.select():
            print r.project.name, r.sku.name, r.date, r.development_mm

        print '-' * 40
        for s in Product.select():
            #print s.project.name, s.sku.name, s.development_mm, s.maintenance_mm
            print hasattr(s, 'project')
            #print s._data

        #u = User.select().where(User.username=='A').get()
        #print type(u.join_date)
        #u = User.getOne(User.username == 'Best')
        #print u
